<!--
 * @Description: Stay hungry，Stay foolish
 * @Author: ''
 * @Date: 2023-09-18 15:34:46
 * @LastEditTime: 2023-09-19 08:48:41
 * @LastEditors: ''
-->
<template>
  <div
    :class="[prefixCls + '-hue']"
    tabindex="0"
    @click="$el.focus()"
    @keydown.esc="handleEscape"
    @keydown.left="handleLeft"
    @keydown.right="handleRight"
    @keydown.up="handleUp"
    @keydown.down="handleDown"
  >
    <div
      ref="container"
      :class="[prefixCls + '-hue-container']"
      @mousedown="handleMouseDown"
      @touchmove="handleChange"
      @touchstart="handleChange">
      <div
        :style="{top: 0, left: `${percent}%`}"
        :class="[prefixCls + '-hue-pointer']">
        <div :class="[prefixCls + '-hue-picker']"></div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { inject,onBeforeUnmount,ref, watch } from 'vue';
import {on,off} from "../../../utils/dom"
import {isClient} from "../../../utils/index"
import { clamp,getTouches } from '../utils';
defineOptions({
  name: 'Hue'
})

const ColorPickerInstance=inject('ColorPickerInstance')

const props=defineProps({
  focused: {
    type: Boolean,
    default: false,
  },
  value: {
    type: Object,
    default: undefined,
  }
})

const handleEscape=()=>{
  ColorPickerInstance.handleOnEscapeKeydown()
}


const emits=defineEmits(['change'])

const normalStep = 1 / 360 * 25;
const jumpStep = 20 * normalStep;
let left=ref(-normalStep)
let right=ref(normalStep)
let up=ref(jumpStep)
let down=ref(-jumpStep)
let powerKey=ref('shiftKey')
let percent=ref(clamp(props.value.hsl.h * 100 / 360, 0, 100))
let container=ref();

const prefixCls=ref('haloe-color-picker')

watch(()=>props.value,()=>{
  percent.value=clamp(props.value.hsl.h * 100 / 360, 0, 100);
})

const change=(_percent)=>{
  percent.value = clamp(_percent, 0, 100);

  const {h, s, l, a} = props.value.hsl;
  const newHue = clamp(_percent / 100 * 360, 0, 360);

  if (h !== newHue) {
    emits('change', {h: newHue, s, l, a, source: 'hsl'});
  }
}

const handleSlide=(e,direction)=>{
  e.preventDefault();
  e.stopPropagation();
  if(e[powerKey.value]){
    change(direction<0?0:100);
    return
  }
  change(percent.value+direction)
}

const getLeft= (e)=> {
  if (!isClient) return;
  // const {container} = this.$refs;
  const xOffset = container.value.getBoundingClientRect().left + window.pageXOffset;
  const pageX = e.pageX || getTouches(e, 'PageX');

  return pageX - xOffset;
}

const getTop= (e)=> {
  if (!isClient) return;
  // const {container} = this.$refs;
  const yOffset = container.value.getBoundingClientRect().top + window.pageYOffset;
  const pageY = e.pageY || getTouches(e, 'PageY');

  return pageY - yOffset;
}

const handleChange =(e)=> {
  e.preventDefault();
  e.stopPropagation();

  const left = getLeft(e);

  if (left < 0) {
    change(0);
    return;
  }

  const { clientWidth } = container.value;

  if (left > clientWidth) {
    change(100);
    return;
  }

  change(left * 100 / clientWidth);
}


const handleLeft=(e)=> {
  handleSlide(e, left.value, 'left');
}
const handleRight= (e)=> {
  handleSlide(e, right.value, 'right');
}
const handleUp =(e)=> {
  handleSlide(e, up.value, 'up');
}
const handleDown= (e)=> {
  handleSlide(e, down.value, 'down');
}

const handleMouseUp= ()=> {
  unbindEventListeners();
}

const handleMouseDown= (e)=> {
  ColorPickerInstance.handleOnDragging(true);
  handleChange(e, true);
  // window.addEventListener('mousemove', this.handleChange, false);
  // window.addEventListener('mouseup', this.handleMouseUp, false);
  on(window, 'mousemove', handleChange);
  on(window, 'mouseup', handleMouseUp);
}

const unbindEventListeners= ()=> {
  // window.removeEventListener('mousemove', this.handleChange);
  // window.removeEventListener('mouseup', this.handleMouseUp);
  off(window, 'mousemove', handleChange);
  off(window, 'mouseup', handleMouseUp);
  // This timeout is required so that the click handler for click-outside
  // has the chance to run before the mouseup removes the dragging flag.
  setTimeout(() => ColorPickerInstance.handleOnDragging(false), 1);
}



onBeforeUnmount(() => {
  unbindEventListeners();
})

/*

    created () {
        if (this.focused) {
            setTimeout(() => this.$el.focus(), 1);
        }
    },
*/ 
</script>

<style>

</style>